// 控制背景运动的定时器：box.mytime
// 控制生成子弹的定时器：kaiShi.planeTimer
// 控制发射子弹的定时器：oBiu.bulletTimer
// 控制生成敌军的定时器：kaiShi.enemyTimer
// 控制敌军移动的定时器：kaiShi.enemyMoveTimer

let box = $('#box'),	// 获取最外层的盒子
	btnArr = $('.btn'),	// 获取按钮集合
	nanDu = $('.nanDu')[0],	// 获取难道选择界面
	kaiShi = $('.kaiShi')[0],	// 获取初始化界面
	zanTing = $('.zanTing')[0],	// 获取暂停界面
	ztHome = $('.zanTing-home')[0],	// 获取暂停界面的返回主页图片
	ztContinue = $('.zanTing-continue')[0],	// 获取暂停界面的
	ztRefresh = $('.zanTing-refresh')[0],
	ksZanTing = $('.kaiShi-zanTing')[0],	// 获取初始化界面的暂停键
	jieShu = $('.jieShu')[0],	// 结束界面
	jsScore = $('.jieShu-score')[0],	// 结束界面中的得分
	chengHaoSpan = $('.chengHao-span')[0],	// 结束界面中称号
	oBiu = $('.kaiShi-biu')[0],	// 获取存放子弹的盒子
	deFen = $('.kaiShi-deFen')[0],
	bgArr = ['img/bg_1.jpg','img/bg_2.jpg','img/bg_3.jpg','img/bg_4.jpg'],	// 定义背景图片数组
	chengHaoArr = [	// 称号数组
		'不堪一击', '初学乍练', '初窥门径', '略有小成', '驾轻就熟', '融会贯通', 
		'炉火纯青', '出类拔萃', '神乎其技', '出神入化', '傲视群雄', '登峰造极', 
		'无与伦比', '所向披靡', '一代宗师', '神功盖世', '举世无双'
	],
	PositionY = 0;	// 初始化背景图片的PositionY属性

function $(idClass) {	// 自定义选择器
	if(idClass.indexOf('#') == 0)
		return document.querySelectorAll(idClass)[0]
	return document.querySelectorAll(idClass)
}

Window.onload = btnPress();	// 页面加载

function btnPress() {	// 难道选择按钮
	for (let i = 0; i < btnArr.length-1; i++) {	// 遍历所有按钮
		btnArr[i].addEventListener('touchstart', (e) => {	// 给按钮添加按下事件
			gameInit(i, {
				x: e.changedTouches[0].clientX,	// 手指X轴位置
				y: e.changedTouches[0].clientY	// 手指Y轴位置
			})
		})
	}
}

function gameInit(level, pos) {	// 初始化模块
	// box.style.background = `url("img/bg_${level + 1}.jpg")`;
	box.style.background = 'url('+ bgArr[level] +')';	// 切换背景图片
	box.style.backgroundSize = '100%';	// 给背景图片添加css样式
	kaiShi.className += ' show';	// 显示初始化界面
	nanDu.className = 'nanDu';	// 隐藏难度选择界面
	deFen.score = 0;
	deFen.innerHTML = deFen.score;
	bgMove()	// 调用背景运动方法
	createPlane(level, pos)	// 调用创建友军方法
	enemy(level)	// 调用生成敌军方法
	// 给初始化界面的返回主页添加按下事件
	ksZanTing.addEventListener('touchstart', cancelAllTimers)	// 移除所有定时器
	ksZanTing.addEventListener('touchstart', again)	// 重新开始
	
}

function bgMove() {	// 背景运动
	(function m(){	// 自执行函数
		kaiShi.bgPos = kaiShi.bgPos || 0;	// 初始化背景Y轴的位置
		kaiShi.bgPos++;
		box.style.backgroundPositionY = kaiShi.bgPos + 'px';	// 背景运动
		box.mytime = requestAnimationFrame(m);
	})()
}

function createPlane(level, pos) {	// 创建友军
	let oPlane = new Image();	// 创建Image对象
	oPlane.src = 'img/plane_1.png';	// 添加飞机图片
	oPlane.width = 100;	// 定义飞机的大小
	oPlane.height = 100;
	oPlane.className = 'yj'
	
	let oLeft = pos.x - oPlane.width/2,	// 让飞机处于中心状态
		oTop = pos.y - oPlane.height/2;
	oPlane.style.cssText = 
		`
			left: ${oLeft}px;
			top: ${oTop}px;
		`
	kaiShi.appendChild(oPlane)	// 将飞机图片添加到初始化界面上
	bullet(oPlane, level)	// 调用生成子弹方法
	oPlane.addEventListener('touchmove', oPlaneMove)	// 给飞机添加手指按下移动事件方法
}

function oPlaneMove(res) {	// 飞机移动方法
	let oPlane = $('.yj')[0],
		clientX = res.changedTouches[0].clientX - oPlane.width/2,	// 获取手指位置
		clientY = res.changedTouches[0].clientY - oPlane.height/2,
		maxX = kaiShi.clientWidth - oPlane.width,	// 获取飞机移动最大移动范围
		maxY = kaiShi.clientHeight - oPlane.height;
	clientX = Math.min(maxX, clientX);	// 使飞机不能超出屏幕
	clientX = Math.max(0,clientX);
	clientY = Math.min(maxY, clientY);
	clientY = Math.max(0,clientY);
	oPlane.style.cssText =
		`
			left: ${clientX}px;
			top: ${clientY}px;
		`
	res.preventDefault() //阻止默认事件
}

function bullet(obj, level) {	// 生成子弹
	kaiShi.planeTimer = setInterval(createBullet, [150, 200, 250, 300][level])
	
	function createBullet() {	// 只生成子弹
		let oBullet = new Image();
		oBullet.src = 'img/fire.png';	// 添加子弹图片
		oBullet.width = 30;
		oBullet.height = 50;
		
		let oLeft = obj.offsetLeft + obj.width/2 - oBullet.width/2,	// 让子弹处于中心状态
			oTop = obj.offsetTop;
		oBullet.style.cssText =
			`
				left: ${oLeft}px;
				top: ${oTop}px;
			`
		oBiu.appendChild(oBullet);	//	添加子弹
		fire(oBullet)	// 调用发射子弹方法
	}
}

function fire(obj) {	// 发射子弹
	if(obj.parentNode){
		let oTop = obj.offsetTop - 20;	// 子弹移动的距离
		if(oTop + obj.height < 0)	// 判断子弹是否超出屏幕
			oBiu.removeChild(obj);	// 移除弹幕
		else{
			obj.style.top = oTop + 'px';	// 弹幕移动
			oBiu.bulletTimer=requestAnimationFrame(() => {
				fire(obj)	
			})
		}
	}
}

function enemy(level) {	// 生成敌军
	kaiShi.enemyTimer = setInterval(createEnemy, [300, 150, 100, 50][level])
	let sum = 1,
		speed = [5,6,7,8][level];
	function createEnemy() {	// 只生成敌军
		let oEnemy = new Image();	// 根据难道选择敌军的速度
		// 根据难道选择决定大飞机出现的频率 0: 小飞机	1: 大飞机
		oEnemy.index = sum % (10 / (level+1) * 3) ? 0 : 1;
		oEnemy.speed = speed * (Math.random() * (1.3 - 0.7) + 0.7);	// 让敌军的速度在0.7-1.3之间波动
		oEnemy.src = ['img/enemy_small.png', 'img/enemy_big.png'][oEnemy.index];	// 添加敌军图片
		oEnemy.HP = [1,5][oEnemy.index];	// 给飞机定义血量
		oEnemy.width = [70, 100][oEnemy.index];
		oEnemy.height = [70, 100][oEnemy.index];
		oEnemy.className = 'dj';
		
		let oLeft = Math.random() * (kaiShi.clientWidth - oEnemy.width),	// 随机敌军X轴位置
			oTop = -oEnemy.height;
		oEnemy.style.cssText =
			`
				left: ${oLeft}px;
				top: ${oTop}px;
			`
		kaiShi.appendChild(oEnemy);	//	添加敌军
		sum++;
		enemyMove(oEnemy)	// 调用敌军移动方法
	}
}

function enemyMove(obj) {	// 敌军移动
	let oPlane = $('.yj')[0];
	let classEnemy = $('.dj');
	if(obj.parentNode){
		let oTop = obj.offsetTop + obj.speed;	// 敌军移动的距离
		if(oTop > kaiShi.clientHeight){	// 判断敌军是否超出屏幕
			deFen.score += [1,5][obj.index];
			deFen.innerHTML = deFen.score;
			kaiShi.removeChild(obj);	// 移除敌军
		}
		else{
			obj.style.top = oTop + 'px';	// 敌军移动
			for(let i = 0; i < oBiu.children.length; i++){	// 遍历所有的子弹
				let oBullet = oBiu.children[i];
				if(coll(obj, oBullet)){	// 判断子弹是否与敌军碰撞，碰撞则
					obj.HP--;	// 敌军血量减一
					oBiu.removeChild(oBullet);	// 移除碰撞的子弹
					if(obj.HP == 0){	// 判断敌军的是否还有血量，没有则
						deFen.score += [1,5][obj.index];	// 根据敌军的类型加分 小飞机加1分 大飞机加5分
						deFen.innerHTML = deFen.score;	// 讲分数加入到界面上
						blast(obj)	// 调用爆炸效果方法
						kaiShi.removeChild(obj);	// 移除敌军
					}
				}
			}
			if(oPlane.parentNode && coll(obj, oPlane)){
				cancelAllTimers()	// 调用取消所有定时器方法
				for (let i = 0; i < classEnemy.length; i++) {	// 遍历所有敌军
					blast(classEnemy[i])
					kaiShi.removeChild(classEnemy[i]);	// 移除敌军
				}
				showJieShu(deFen.score,oPlane)	// 调用显示结束界面方法
				blast(oPlane)	// 调用爆炸方法
			}
			kaiShi.enemyMoveTimer=requestAnimationFrame(() => {
				enemyMove(obj)	// 调用敌军移动方法
			})
		}
	}
}

function coll(enemy, obj) {	// 碰撞方法
	let l1 = enemy.offsetLeft,
		r1 = l1 + enemy.width,
		t1 = enemy.offsetTop,
		b1 = t1 + enemy.height,
		l2 = obj.offsetLeft,
		r2 = l2 + obj.width,
		t2 = obj.offsetTop,
		b2 = t2 + obj.height;
		
	if(!(l1 > r2 || r1 < l2 || t1 > b2 || b1 < t2))	// 判断是否碰撞，是则
		return true;	// 返回true
	return false;	// 否则,返回true
}

function blast(obj) {	// 爆炸效果方法
	if(obj.className == 'dj'){	// 判断是否是敌军，是则
		let oBlast = new Image();	// 创建爆炸Image对象
		// 根据飞机类型添加不同的爆炸图片
		oBlast.src = ['img/boom_small.png', 'img/boom_big.png'][obj.index]
		oBlast.className = 'boom1';	// 给敌军添加逐渐消失的效果
		oBlast.width = obj.width;
		oBlast.height = obj.height;
		
		let oLeft = obj.offsetLeft,
			oTop = obj.offsetTop;
		oBlast.style.cssText = 
			`
				left: ${oLeft}px;
				top: ${oTop}px;
			`
		kaiShi.appendChild(oBlast);
		setTimeout(() => {	// 延迟1s触发
			kaiShi.removeChild(oBlast);	// 移除爆炸图片
		}, 1000)
	}else if(obj.className == 'yj')
		obj.className += ' boom2'	// 给友军添加闪烁的效果
}

function cancelAllTimers() {	// 移除所有定时器方法
	cancelAnimationFrame(kaiShi.enemyMoveTimer)	// 移除敌军移动的定时器
	clearInterval(kaiShi.enemyTimer)	// 移除生成敌军的定时器
	cancelAnimationFrame(oBiu.bulletTimer)	// 移除发射子弹的定时器
	clearInterval(kaiShi.planeTimer)	// 移除生成子弹的定时器
	cancelAnimationFrame(box.mytime)	// 移除背景运动的定时器
}

function showJieShu(score,oPlane) {	// 显示结束界面方法
	oPlane.removeEventListener('touchmove',oPlaneMove)	// 移除友军移动事件
	jieShu.className += ' show';	// 显示结束界面
	jsScore.innerHTML = score;	// 讲得分放入结束界面的得分中
	// 根据分数获得不同称号
	chengHaoSpan.innerHTML = chengHaoArr[jsScore.innerHTML.length >= 3 ? parseInt(score/100) : 0];
	btnArr[btnArr.length-1].addEventListener('touchstart', again)	// 给重新开始按钮添加按下事件
}

function again() {	// 重新开始方法
	let oBullet = oBiu.children,	// 获取所有的子弹
		oPlane = $('.yj')[0],
		classEnemy = $('.dj');	// 获取所有的敌军
		
	if(classEnemy.length) {	// 判断是否存在敌军，存在则
		for (let i = 0; i < classEnemy.length; i++) {	// 遍历所有敌军
			kaiShi.removeChild(classEnemy[i]);// 移除敌军
		}
	}
	if(oBullet.length){	// 判断是否存在子弹，存在则
		for (let i = 0; i < oBullet.length; i++) {	// 遍历所有子弹
			oBiu.removeChild(oBullet[i]);	// 移除子弹
		}
	}
	if(oPlane.parentNode)	// 判断是否获取到友军
		kaiShi.removeChild(oPlane);	// 移除友军
	deFen.score = 0;	// 得分清零
	deFen.innerHTML = deFen.score;
	jieShu.className = 'jieShu';	// 隐藏结束界面
	kaiShi.className += 'kaiShi';	// 隐藏初始界面
	nanDu.className += ' show';	// 显示难度选择界面
}